home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / Updates / PowerPC / jpeg2ps / asc85ec.c next >
C/C++ Source or Header  |  2000-05-16  |  3KB  |  126 lines

  1. /* ASCII85 and Hex encoding for PostScript Level 2 and PDF */
  2. /* (C) Thomas Merz 1994-99 */
  3.  
  4. #include <stdio.h>
  5. #include <fcntl.h>
  6.  
  7. #ifdef DOS
  8. #include <io.h>
  9. #include <stdlib.h>
  10. #endif
  11.  
  12. #include "psimage.h"
  13.  
  14. typedef unsigned char byte;
  15.  
  16. static unsigned char buf[4];
  17. static unsigned long power85[5] = { 1L, 85L, 85L*85, 85L*85*85, 85L*85*85*85};
  18. static int outbytes;        /* Number of characters in an output line */
  19.  
  20. /* read 0-4 Bytes. result: number of bytes read */
  21. static int 
  22. ReadSomeBytes P1(FILE *, in)
  23. {
  24.   register int count, i;
  25.  
  26.   for (count = 0; count < 4; count++) {
  27.     if ((i = getc(in)) == EOF)
  28.       break;
  29.     else
  30.       buf[count] = (byte) i;
  31.   }
  32.   return count;
  33. }
  34.  
  35. /* Two percent characters at the start of a line will cause trouble
  36.  * with some post-processing software. In order to avoid this, we
  37.  * simply insert a line break if we encounter a percent character
  38.  * at the start of the line. Of course, this rather simplistic
  39.  * algorithm may lead to a large line count in pathological cases,
  40.  * but the chance for hitting such a case is very small, and even
  41.  * so it's only a cosmetic flaw and not a functional restriction.
  42.  */
  43.  
  44. static void 
  45. outbyte P2(byte, c, FILE *, out)
  46. {    /* output one byte */
  47.  
  48.   if (fputc(c, out) == EOF) {
  49.     fprintf(stderr, "jpeg2ps: write error - exit!\n");
  50.     exit(1);
  51.   }
  52.  
  53.   if (++outbytes > 63 ||        /* line limit reached */
  54.     (outbytes == 1 && c == '%') ) {    /* caution: percent character at start of line */
  55.     fputc('\n', out);            /* insert line feed */
  56.     outbytes = 0;
  57.   }
  58. }
  59.  
  60. int
  61. ASCII85Encode P2(FILE *, in, FILE *, out)
  62. {
  63.   register int i, count;
  64.   unsigned long word, v;
  65.  
  66.   outbytes = 0;
  67.  
  68.   /* 4 bytes read ==> output 5 bytes */
  69.   while ((count = ReadSomeBytes(in)) == 4) {
  70.     word = ((unsigned long)(((unsigned int)buf[0] << 8) + buf[1]) << 16) +
  71.                    (((unsigned int)buf[2] << 8) + buf[3]);
  72.     if (word == 0)
  73.       outbyte('z', out);       /* shortcut for 0 */
  74.     else
  75.       /* calculate 5 ASCII85 bytes and output them */
  76.       for (i = 4; i >= 0; i--) {
  77.     v = word / power85[i];
  78.     outbyte((byte) (v + '!'), out);
  79.     word -= v * power85[i];
  80.       }
  81.   }
  82.  
  83.   word = 0;
  84.  
  85.   if (count != 0) {   /* 1-3 bytes left */
  86.     for (i = count-1; i >= 0; i--)   /* accumulate bytes */
  87.       word += (unsigned long)buf[i] << 8 * (3-i);
  88.     
  89.     /* encoding as above, but output only count+1 bytes */
  90.     for (i = 4; i >= 4-count; i--) {
  91.       v = word / power85[i];
  92.       outbyte((byte) (v + '!'), out);
  93.       word -= v * power85[i];
  94.     }
  95.   }
  96.  
  97.   fputc('~', out);    /* EOD marker */
  98.   fputc('>', out);
  99.   return 0;
  100. }
  101.  
  102. void 
  103. ASCIIHexEncode P2(FILE *, in, FILE *, out) {
  104.   static char buffer[512];
  105.   static char BinToHex[] = "0123456789ABCDEF";
  106.   int CharsPerLine;
  107.   size_t i, n;
  108.   unsigned char *p;
  109.  
  110.   CharsPerLine = 0;
  111.   fputc('\n', out);
  112.  
  113.   while ((n = fread(buffer, 1, sizeof(buffer), in)) != 0)
  114.     for (i = 0, p = (unsigned char *) buffer; i < n; i++, p++) {
  115.       fputc(BinToHex[*p>>4], out);           /* first nibble  */
  116.       fputc(BinToHex[*p & 0x0F], out);       /* second nibble */
  117.       if ((CharsPerLine += 2) >= 64) {
  118.         fputc('\n', out);
  119.         CharsPerLine = 0;
  120.       }
  121.     }
  122.  
  123.   fputc('>', out);         /* EOD marker for PostScript hex strings */
  124. }
  125.  
  126.